SWEP.HoldType = "knife"
SWEP.ViewModelFOV = 127
SWEP.ViewModelFlip = false
SWEP.ViewModel = "models/The_Sniper_9/DoctorWho/Extras/ScrewDrivers/laserscrewdriver.mdl"
SWEP.WorldModel = "models/The_Sniper_9/DoctorWho/Extras/ScrewDrivers/laserscrewdriver.mdl"
SWEP.ViewModelBoneMods = {
	["static_prop"] = { scale = Vector(1, 1, 1), pos = Vector(15.894, 30, 0), angle = Angle(99.231, 38.362, 35.469) }
}
SWEP.VElements = {
	["glow"] = { type = "Sprite", sprite = "sprites/glow03", bone = "static_prop", rel = "", pos = Vector(5.767, 4.25, -1), size = { x = 1, y = 1 }, color = Color(255, 255, 255, 255), nocull = true, additive = true, vertexalpha = true, vertexcolor = true, ignorez = false},
	["screwdriver"] = { type = "Model", model = "models/The_Sniper_9/DoctorWho/Extras/ScrewDrivers/laserscrewdriver.mdl", bone = "static_prop", rel = "", pos = Vector(0.944, 4, -4), angle = Angle(32.819, 0, 0), size = Vector(0.649, 0.649, 0.649), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
}
SWEP.WElements = {	
	["screwdriver"] = { type = "Model", model = "models/The_Sniper_9/DoctorWho/Extras/ScrewDrivers/laserscrewdriver.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(2.805, 1.837, -1.499), angle = Angle(-85.264, 0, 0), size = Vector(0.5, 0.5, 0.5), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
}

SWEP.PrintName = "Laser Screwdriver"
SWEP.Author = "RononDex"
SWEP.Purpose = ""
SWEP.Instructions = "Hush now, and listen to your Master."
SWEP.Category = "Doctor Who"
SWEP.Spawnable=true
SWEP.AdminSpawnable=false
SWEP.Base = "weapon_base"
SWEP.Slot = 1
SWEP.SlotPos = 4
SWEP.DrawAmmo	= false
SWEP.DrawCrosshair = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo	= "none"

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo	= "none"

function SWEP:PrimaryAttack()

	if self.CoolDown >= 100 and not self.Overheated then
		self.Overheated = true
		self.Owner:SetNWBool("Overheated",self.Overheated)
		timer.Simple(5, function() self.CoolDown = 0; self:SetNWInt("CoolDown",self.CoolDown); self.Overheated = false; self.Owner:SetNWBool("Overheated",self.Overheated) end)
	end
	
	local tr = self.Owner:GetEyeTrace()
	local ent = tr.Entity
	local pos = self.Owner:GetPos()
	local dist = (pos - ent:GetPos()):Length()
	local ephys 

	if not self.Overheated and dist < 1000 then
		self.CoolDown = self.CoolDown + 1
		self:SetNWInt("CoolDown",self.CoolDown)
		if ValidEntity(ent) then
			ephys = ent:GetPhysicsObject()
			if ent:IsNPC() then
				self:Dissolve(ent)
			elseif ent:GetClass()=="prop_physics" then
				ephys:ApplyForceCenter(Vector(1000,1000,1000))
				local fx = EffectData()
					fx:SetOrigin(tr.HitPos)
				util.Effect("Sparks",fx)
			end
		end
	end
end

function SWEP:Dissolve(ent)

	local t = "Laser_Screwdriver_"..self.Weapon:EntIndex()
	ent:SetKeyValue("targetname",t)			
	local e = ents.Create( "env_entity_dissolver" );				
	e:SetKeyValue( "dissolvetype", 3 );
	e:SetKeyValue( "magnitude", 0 );
	e:SetKeyValue( "target", t );
	e:SetPos( ent:GetPos() );
	e:SetPhysicsAttacker( self.Owner );
	e:Spawn();
	e:Fire( "Dissolve", t, 0 );
	e:Fire( "Kill", "", 0.1 );
	e:Remove();
	
end

if CLIENT then


	
end
function SWEP:Think()

	if self.CoolDown > 0 and not self.Overheated then
		if not self.Owner:KeyDown(IN_ATTACK) then
			self.CoolDown = self.CoolDown - 1
			self:SetNWInt("CoolDown",self.CoolDown)
		end
	end
end

function SWEP:Initialize()
 
	self.CoolDown = 0
	
    if CLIENT then
        self:CreateModels(self.VElements) // create viewmodels
        self:CreateModels(self.WElements) // create worldmodels
         
        --SWEP View Model Code
        self.BuildViewModelBones = function( s )
            if LocalPlayer():GetActiveWeapon() == self and self.ViewModelBoneMods then
                for k, v in pairs( self.ViewModelBoneMods ) do
                    local bone = s:LookupBone(k)
                    if (!bone) then continue end
                    local m = s:GetBoneMatrix(bone)
                    if (!m) then continue end
                    m:Scale(v.scale)
                    m:Rotate(v.angle)
                    m:Translate(v.pos)
                    s:SetBoneMatrix(bone, m)
                end
            end
        end
         
    end
end

hook.Add("PlayerDeath","LaserScrewdriverDeath", function(p)
	local vm = p:GetViewModel()
	if p:GetActiveWeapon()=="laser_screwdriver" then
		vm:SetColor(Color(255,255,255,255))
	end
end)

function SWEP:Holster()

	if CLIENT then
		self.Owner:GetViewModel():SetColor(Color(255,255,255,255))
	end
	return true
end

function SWEP:OnRemove()
     
    if CLIENT then
        self:RemoveModels()
    end
     
end
     
 
if CLIENT then
 
	hook.Add("HUDPaint","LScrewdriverBeam",function()
		DrawLaser()
	end)
	
	function DrawLaser()
		local p = LocalPlayer()
		local mdl = p:GetViewModel()
		local overheated = p:GetNWBool("Overheated",false)
		local w
		if not overheated then
			if p:KeyDown(IN_ATTACK) then
				w = 1
			else
				w = 0
			end
		else
			w = 0
		end
		render.SetMaterial( Material("cable/redlaser") )
		render.DrawBeam(mdl:GetPos()+mdl:GetRight()*2.7+mdl:GetForward()*3.5+mdl:GetUp()*-0.75, p:GetEyeTrace().HitPos, w, 0, 12.5, Color(255, 0, 0, 255))		
	end
	
	function SWEP:DrawHUD()
	
		local cd = self:GetNWInt("CoolDown",0)
		draw.WordBox(9,ScrW()-240,ScrH()-115,"Heat Levels: "..cd.."%","Default",Color(0,0,0,80),Color(255,220,0,220));

	end	
 
    SWEP.vRenderOrder = nil
    function SWEP:ViewModelDrawn()
         
		local mdl = self.Owner:GetViewModel()
		
		
		
        local vm = self.Owner:GetViewModel()
        if !ValidEntity(vm) then return end
         
        if (!self.VElements) then return end
         
        if vm.BuildBonePositions ~= self.BuildViewModelBones then
            vm.BuildBonePositions = self.BuildViewModelBones
        end
		
        // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
        vm:SetColor(255,255,255,1) 

        
        if (!self.vRenderOrder) then
             
            // we build a render order because sprites need to be drawn after models
            self.vRenderOrder = {}
 
            for k, v in pairs( self.VElements ) do
                if (v.type == "Model") then
                    table.insert(self.vRenderOrder, 1, k)
                elseif (v.type == "Sprite" or v.type == "Quad") then
                    table.insert(self.vRenderOrder, k)
                end
            end
             
        end
 
        for k, name in ipairs( self.vRenderOrder ) do
         
            local v = self.VElements[name]
            if (!v) then self.vRenderOrder = nil break end
         
            local model = v.modelEnt
            local sprite = v.spriteMaterial
             
            if (!v.bone) then continue end
             
            local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
             
            if (!pos) then continue end
             
            if (v.type == "Model" and ValidEntity(model)) then
 
                model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
                ang:RotateAroundAxis(ang:Up(), v.angle.y)
                ang:RotateAroundAxis(ang:Right(), v.angle.p)
                ang:RotateAroundAxis(ang:Forward(), v.angle.r)
 
                model:SetAngles(ang)
                model:SetModelScale(v.size)
                 
                if (v.material == "") then
                    model:SetMaterial("")
                elseif (model:GetMaterial() != v.material) then
                    model:SetMaterial( v.material )
                end
                 
                if (v.skin and v.skin != model:GetSkin()) then
                    model:SetSkin(v.skin)
                end
                 
                if (v.bodygroup) then
                    for k, v in pairs( v.bodygroup ) do
                        if (model:GetBodygroup(k) != v) then
                            model:SetBodygroup(k, v)
                        end
                    end
                end
                 
                if (v.surpresslightning) then
                    render.SuppressEngineLighting(true)
                end
                 
                render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
                render.SetBlend(v.color.a/255)
                model:DrawModel()
                render.SetBlend(1)
                render.SetColorModulation(1, 1, 1)
                 
                if (v.surpresslightning) then
                    render.SuppressEngineLighting(false)
                end
                 
            elseif (v.type == "Sprite" and sprite) then
                
				if self.Owner:KeyDown(IN_ATTACK) and not self.Overheated then
				
					local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
					render.SetMaterial(sprite)
					render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
                end
            elseif (v.type == "Quad" and v.draw_func) then
                 
                local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
                ang:RotateAroundAxis(ang:Up(), v.angle.y)
                ang:RotateAroundAxis(ang:Right(), v.angle.p)
                ang:RotateAroundAxis(ang:Forward(), v.angle.r)
                 
                cam.Start3D2D(drawpos, ang, v.size)
                    v.draw_func( self )
                cam.End3D2D()
 
            end
             
        end
         
    end
 
    SWEP.wRenderOrder = nil
    function SWEP:DrawWorldModel()
         
        if (self.ShowWorldModel == nil or self.ShowWorldModel) then
            self:DrawModel()
        end
         
        if (!self.WElements) then return end
         
        if (!self.wRenderOrder) then
 
            self.wRenderOrder = {}
 
            for k, v in pairs( self.WElements ) do
                if (v.type == "Model") then
                    table.insert(self.wRenderOrder, 1, k)
                elseif (v.type == "Sprite" or v.type == "Quad") then
                    table.insert(self.wRenderOrder, k)
                end
            end
 
        end
         
        if (ValidEntity(self.Owner)) then
            bone_ent = self.Owner
        else
            // when the weapon is dropped
            bone_ent = self
        end
         
        for k, name in pairs( self.wRenderOrder ) do
         
            local v = self.WElements[name]
            if (!v) then self.wRenderOrder = nil break end
             
            local pos, ang
             
            if (v.bone) then
                pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
            else
                pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
            end
             
            if (!pos) then continue end
             
            local model = v.modelEnt
            local sprite = v.spriteMaterial
             
            if (v.type == "Model" and ValidEntity(model)) then
 
                model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
                ang:RotateAroundAxis(ang:Up(), v.angle.y)
                ang:RotateAroundAxis(ang:Right(), v.angle.p)
                ang:RotateAroundAxis(ang:Forward(), v.angle.r)
 
                model:SetAngles(ang)
                model:SetModelScale(v.size)
                 
                if (v.material == "") then
                    model:SetMaterial("")
                elseif (model:GetMaterial() != v.material) then
                    model:SetMaterial( v.material )
                end
                 
                if (v.skin and v.skin != model:GetSkin()) then
                    model:SetSkin(v.skin)
                end
                 
                if (v.bodygroup) then
                    for k, v in pairs( v.bodygroup ) do
                        if (model:GetBodygroup(k) != v) then
                            model:SetBodygroup(k, v)
                        end
                    end
                end
                 
                if (v.surpresslightning) then
                    render.SuppressEngineLighting(true)
                end
                 
                render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
                render.SetBlend(v.color.a/255)
                model:DrawModel()
                render.SetBlend(1)
                render.SetColorModulation(1, 1, 1)
                 
                if (v.surpresslightning) then
                    render.SuppressEngineLighting(false)
                end
                 
            elseif (v.type == "Sprite" and sprite) then
                if self.Owner:KeyDown(IN_ATTACK) and not self.Overheated then
					local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
					render.SetMaterial(sprite)
					render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
                 end
            elseif (v.type == "Quad" and v.draw_func) then
                 
                local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
                ang:RotateAroundAxis(ang:Up(), v.angle.y)
                ang:RotateAroundAxis(ang:Right(), v.angle.p)
                ang:RotateAroundAxis(ang:Forward(), v.angle.r)
                 
                cam.Start3D2D(drawpos, ang, v.size)
                    v.draw_func( self )
                cam.End3D2D()
 
            end
             
        end
         
    end
 
    function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
         
        local bone, pos, ang
        if (tab.rel and tab.rel != "") then
             
            local v = basetab[tab.rel]
             
            if (!v) then return end
             
            // Technically, if there exists an element with the same name as a bone
            // you can get in an infinite loop. Let's just hope nobody's that stupid.
            pos, ang = self:GetBoneOrientation( basetab, v, ent )
             
            if (!pos) then return end
             
            pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
            ang:RotateAroundAxis(ang:Up(), v.angle.y)
            ang:RotateAroundAxis(ang:Right(), v.angle.p)
            ang:RotateAroundAxis(ang:Forward(), v.angle.r)
                 
        else
         
            bone = ent:LookupBone(bone_override or tab.bone)
 
            if (!bone) then return end
             
            pos, ang = Vector(0,0,0), Angle(0,0,0)
            local m = ent:GetBoneMatrix(bone)
            if (m) then
                pos, ang = m:GetTranslation(), m:GetAngle()
            end
             
            if (ValidEntity(self.Owner) and self.Owner:IsPlayer() and
                ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
                ang.r = -ang.r // Fixes mirrored models
            end
         
        end
         
        return pos, ang
    end
 
    function SWEP:CreateModels( tab )
 
        if (!tab) then return end
 
        // Create the clientside models here because Garry says we can't do it in the render hook
        for k, v in pairs( tab ) do
            if (v.type == "Model" and v.model and v.model != "" and (!ValidEntity(v.modelEnt) or v.createdModel != v.model) and
                    string.find(v.model, ".mdl") and file.Exists ("../"..v.model) ) then
                 
                v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
                if (ValidEntity(v.modelEnt)) then
                    v.modelEnt:SetPos(self:GetPos())
                    v.modelEnt:SetAngles(self:GetAngles())
                    v.modelEnt:SetParent(self)
                    v.modelEnt:SetNoDraw(true)
                    v.createdModel = v.model
                else
                    v.modelEnt = nil
                end
                 
            elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite) 
                and file.Exists ("../materials/"..v.sprite..".vmt")) then
                 
                local name = v.sprite.."-"
                local params = { ["$basetexture"] = v.sprite }
                // make sure we create a unique name based on the selected options
                local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
                for i, j in pairs( tocheck ) do
                    if (v[j]) then
                        params["$"..j] = 1
                        name = name.."1"
                    else
                        name = name.."0"
                    end
                end
 
                v.createdSprite = v.sprite
                v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
                 
            end
        end         
    end
 
    function SWEP:RemoveModels()
        if (self.VElements) then
            for k, v in pairs( self.VElements ) do
                if (ValidEntity( v.modelEnt )) then v.modelEnt:Remove() end
            end
        end
        if (self.WElements) then
            for k, v in pairs( self.WElements ) do
                if (ValidEntity( v.modelEnt )) then v.modelEnt:Remove() end
            end
        end
        self.VElements = nil
        self.WElements = nil
    end
end